//
//  BaseViewController.m
//  FPTest
//
//  Created by zhaohong on 2017/11/7.
//  Copyright © 2017年 zhaohong. All rights reserved.
//

#import "BaseViewController.h"
#include <objc/runtime.h>

@interface BaseViewController ()
{
    MBProgressHUD *hud; //!< hud第三方动画
    
        BaseTableView *_baseTableView;//!< 当子控制器用到baseTableView时，用此变量控制上拉下拉动画的结束
        BOOL _isPullDown;//!< 是否是下拉刷新
    //    BaseScrollView *_baseScrollView;//!< 当子控制器用到baseTableView时，用此变量控制上拉下拉动画的结束
    
    NSLayoutConstraint *hudBottomVToTopConstraint;//!<加载hud层距离顶部的距离
    NSLayoutConstraint *requestFailVToTopConstraint;//!<网络请求失败的view距离顶部的距离
    
    BOOL isCanReducePageNum;//是否可以减少pageNum在上拉失败时的页数
    
    
}

@property (nonatomic , strong) UIImageView *failImageView;//网络判断结果显示图片
@property (nonatomic , strong) UILabel *failLabel;//网络判断结果提示语句

@end

@implementation BaseViewController

- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    
    
    
    NSArray *viewControllers = self.navigationController.viewControllers;
    if (viewControllers.count > 1) {
        //返回按钮
        UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        [backBtn setBackgroundImage:[UIImage imageNamed:@"back_btn_ios7"] forState:UIControlStateNormal];
        [backBtn addTarget:self action:@selector(backLastView) forControlEvents:UIControlEventTouchUpInside];
        backBtn.frame = CGRectMake(0, 0, 10, 18);
        
        UIBarButtonItem *backItem = [[UIBarButtonItem alloc]initWithCustomView:backBtn];
        self.navigationItem.leftBarButtonItem = backItem;
        
        //不是底部导航栏时隐藏底部标签栏控制器
        [self setHidesBottomBarWhenPushed:YES];
        
    }
    
    //设置导航栏不覆盖内容
    self.navigationController.navigationBar.translucent = NO;
    
    //是否隐藏导航栏
    if (self.isHideNaviBar) {
        [self.navigationController setNavigationBarHidden:YES animated:YES];
    }else
    {
        [self.navigationController setNavigationBarHidden:NO animated:YES];
    }
}


- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    //设置返回上一个界面动画，可以实现界面慢速右拉返回上一个界面
    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.navigationController.interactivePopGestureRecognizer.delegate = nil;
    }
    
    
    
    _isDIYLoading = NO;
    //初始化自定义的hud，failView界面
    if (self.hudBaseView == nil) {
        [self diyAwakeFromNib];
    }
    //默认关闭网络请求动画,不可以使用self.isLoading = NO;以免造成冲突
    [self hideHUD];
    
    //如果是设置的要隐藏导航栏，则隐藏
    if (self.isHideNaviBar) {
        [self.navigationController setNavigationBarHidden:YES animated:NO];
    }
    
    self.isSwipGesture = YES;
    //获取用户信息
    self.user = [User shareUserContext];
    
}




/**
 *  设置导航栏顶部字体
 *
 *  @param title 导航栏字
 */
#pragma mark 设置导航栏顶部字体
- (void)setTitle:(NSString *)title
{
    [super setTitle:title];
    
    UILabel *titleLabel = [[UILabel  alloc]initWithFrame:CGRectZero];
    titleLabel.backgroundColor = [UIColor clearColor];
    titleLabel.font = [UIFont systemFontOfSize:17];
    titleLabel.text = title;
    titleLabel.textColor = [UIColor colorWithHexString:@"#005000"];
    titleLabel.textAlignment = NSTextAlignmentCenter;
    [titleLabel sizeToFit];
    self.navigationItem.titleView = titleLabel;
}

#pragma mark 初始化控制器时，添加一层用于加载hud动画的view，并再加载一层用于表示网络请求失败的view，点击网络加载失败的view可以重新触发网络请求
- (void)diyAwakeFromNib{
    
    //添加一个hudBaseView
    self.hudBaseView = [[UIView alloc]initWithFrame:CGRectZero];
    self.hudBaseView.translatesAutoresizingMaskIntoConstraints = NO;
    self.hudBaseView.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:self.hudBaseView];
    
    
    NSDictionary *viewDics2 = NSDictionaryOfVariableBindings(_hudBaseView);
    NSArray *constraints2 = [NSLayoutConstraint constraintsWithVisualFormat:
                             @"|[_hudBaseView]|"
                                                                    options:0 metrics:nil views:viewDics2];
    [self.view addConstraints:constraints2];
    constraints2 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_hudBaseView]|" options:0
                                                           metrics:nil
                                                             views:viewDics2];
    [self.view addConstraints:constraints2];
    
    hudBottomVToTopConstraint = constraints2[0];
    
    
    //将_hudBaseView放在上层
    if (self.view.subviews.count>1) {
        [self.view insertSubview:_hudBaseView atIndex:1];
        
    }
    
    //网络请求失败层view
    _requestFailView = [[UIView alloc]initWithFrame:CGRectMake(0, 64, 0, 0)];
    _requestFailView.translatesAutoresizingMaskIntoConstraints = NO;
    _requestFailView.hidden = YES;
    [self.view addSubview:_requestFailView];
    NSDictionary *viewDics4 = NSDictionaryOfVariableBindings(_requestFailView);
    NSArray *constraints4 = [NSLayoutConstraint constraintsWithVisualFormat:
                             @"|[_requestFailView]|"
                                                                    options:0 metrics:nil views:viewDics4];
    [self.view addConstraints:constraints4];
    
    constraints4 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_requestFailView]|" options:0
                                                           metrics:nil
                                                             views:viewDics4];
    [self.view addConstraints:constraints4];
    requestFailVToTopConstraint = constraints4[0];
    //将_requestFailView放在上层
    if (self.view.subviews.count>2) {
        [self.view insertSubview:_requestFailView atIndex:2];
        
    }
    
    
    //网络请求错误时显示点击屏幕刷新
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(requestDataAgain)];
    [_requestFailView addGestureRecognizer:tapGesture];
    
    
    
    _failImageView = [[UIImageView alloc]initWithFrame:CGRectZero];
    _failImageView.image = [UIImage imageNamed:@"网络抽风"];
    _failImageView.translatesAutoresizingMaskIntoConstraints = NO;
    [_requestFailView addSubview:_failImageView];
    
    NSLayoutConstraint *constraintFailImageV = [NSLayoutConstraint constraintWithItem:_failImageView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual
                                                                               toItem:_requestFailView attribute:NSLayoutAttributeCenterX multiplier:1.0f
                                                                             constant:0.0f];
    [_requestFailView addConstraint:constraintFailImageV];
    constraintFailImageV = [NSLayoutConstraint constraintWithItem:_failImageView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual
                                                           toItem:_requestFailView attribute:NSLayoutAttributeCenterY multiplier:1.0f
                                                         constant:-60];
    
    [_requestFailView addConstraint:constraintFailImageV];
    
    
    
    //网络错误提示标签
    _failLabel = [[UILabel alloc]initWithFrame:CGRectZero];
    _failLabel.translatesAutoresizingMaskIntoConstraints = NO;
    _failLabel.text = @"网络抽风，猛戳重试";
    _failLabel.textColor = [UIColor hexColor:@"959BAA"];
    
    [_requestFailView addSubview:_failLabel];
    
    NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:_failLabel attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual
                                                                     toItem:_failImageView attribute:NSLayoutAttributeCenterX multiplier:1.0f
                                                                   constant:0.0f];
    [_requestFailView addConstraint:constraint];
    constraint = [NSLayoutConstraint constraintWithItem:_failLabel attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual
                                                 toItem:_failImageView attribute:NSLayoutAttributeBottom multiplier:1.0f
                                               constant:15.0f];
    
    [_requestFailView addConstraint:constraint];
    
    _failLabel.userInteractionEnabled = NO;
    
    _requestFailView.backgroundColor = [UIColor colorWithHexString:@"#282a36"];
    
    
}




#pragma mark -------------------------requestDataDelegate-------------------------

#pragma mark 重新请求网络
- (void)requestDataAgain
{
    //当上拉加载失败的时候，pageNum减1
    [self reducePageNum];
    
    if ([Constant netWorkingStatus] == 0)
    {
        //无网络连接 不操作
    }else
    {
        //隐藏加载失败时的提示界面
        _requestFailView.hidden = YES;
    }
}

#pragma mark 当上拉加载失败的时候，pageNum减1
- (void)reducePageNum
{
    //判断如果是上拉加载，且pageNum已经大于1的情况，这时才减1
    if (isCanReducePageNum && _pageNum>1) {
        _pageNum--;
        isCanReducePageNum = NO;
    }
}

#pragma mark 请求网路
- (void)requestData
{
    //当调用此方法时默认为进入页面数据请求加载，所以loading类型默认为默认类型
    self.loadingType = LoadingNormal;
    
    
    //如果不是下拉刷新和上拉加载数据时才开启加载动画
    if (!(_isPullDown||_isPullUp))
    {
        //开启加载动画
        self.isLoading = YES;
    }
}

#pragma mark 网络请求成功
- (void)requestSuccess
{
    //关闭加载动画
    self.isLoading = NO;
    
    //取消tableView的下拉刷新上拉加载的动画
    [_baseTableView doneLoadingTableViewData];
   
    
}

-(void)requestTooLong
{
    
    _failImageView.image = [UIImage imageNamed:@"网络抽风"];
    _failLabel.text = @"网络异常,请稍后重试";
    /**
     * 调用可以加载一个网络请求失败的图片在view上，点击可重新请求网络
     */
    self.isLoading = NO;//关闭加载动画
    _requestFailView.hidden = NO;
    
    //将下拉上拉状态设为no
    _isPullDown=NO;
    _isPullUp = NO;
    
    //取消tableView的下拉刷新上拉加载的动画
    [_baseTableView doneLoadingTableViewData];
    
    //当上拉加载失败的时候，pageNum减1
    [self reducePageNum];
}

#pragma mark 网络请求失败
- (void)requestFail
{
    

    if ([Constant netWorkingStatus] == 0)
    {
        _failImageView.image = [UIImage imageNamed:@"无网络"];
        _failLabel.text = @"并没有网络";
    }else
    {
        _failImageView.image = [UIImage imageNamed:@"网络抽风"];
        _failLabel.text = @"网络抽风，猛戳重试";
    }
    
    
    /**
     * 调用可以加载一个网络请求失败的图片在view上，点击可重新请求网络
     */
    self.isLoading = NO;//关闭加载动画
    _requestFailView.hidden = NO;
    
    
    //将下拉上拉状态设为no
    _isPullDown=NO;
    _isPullUp = NO;
    
    //取消tableView的下拉刷新上拉加载的动画
    [_baseTableView doneLoadingTableViewData];
   
    //当上拉加载失败的时候，pageNum减1
    [self reducePageNum];
}


#pragma mark--------------------------------UITableViewEventDelegate
/**
 *  下拉刷新，将刷新页数更新为1，调整是在上拉还是下拉的bool值
 *
 *  @param tableView
 */
#pragma mark 下拉刷新
- (void)pullDown:(BaseTableView *)tableView
{
    _baseTableView = tableView;
    _isPullDown = YES;
    _isPullUp = NO;
    _pageNum = 1;
    _lastItme = 0;
}


/**
 *  上拉加载，将刷新页数自加1，调整是在上拉还是下拉的bool值
 *
 *  @param tableView
 */
#pragma mark 上拉加载
- (void)pullUp:(BaseTableView *)tableView
{
    
    
    _baseTableView = tableView;
    _isPullUp = YES;
    _isPullDown = NO;
    _pageNum++;
    _lastItme += 20;
    //如果是无网络情况调用，则pageNum不加1
    if (AFNetworkReachabilityStatusNotReachable == [Constant netWorkingStatus]) {
        _pageNum--;
    }
    
    
    isCanReducePageNum = YES;
    
}





#pragma --mark  ---------------------------------------HUD方法
#pragma mark 是否显示或隐藏加载HUD动画
- (void)setIsLoading:(BOOL)loading
{
    if (loading) {
        [self showLoadingWithType:LoadingNormal];
    }else
    {
        //非页面内加载会延迟0.5s再隐藏loading
        if (self.loadingType != LoadingNormal) {
            [self performSelector:@selector(hideHUD) withObject:nil afterDelay:0.5];
        }else
        {
            [self hideHUD];
        }
    }
    
}

#pragma mark 根据不同的类型打开不同的loading类型
- (void)showLoadingWithType:(LoadingType)loadingType
{
    self.loadingType = loadingType;
    for (UIView *view in self.hudBaseView.subviews) {
        [view removeFromSuperview];
    }
    
    
    //区分是页面内加载还是阻塞式加载，不同的加载方式hud加载到不同的view上
    if (loadingType == LoadingNormal || loadingType == LoadingHaveBackground) {
        self.hudBaseView.hidden = NO;
        hud = [MBProgressHUD showHUDAddedTo:self.hudBaseView animated:YES];
        
    }else
    {
        UIView *windowView = [UIApplication sharedApplication].keyWindow;
        for (UIView *view in windowView.subviews) {
            if ([view isKindOfClass:[MBProgressHUD class]]) {
                [view removeFromSuperview];
            }
        }
        hud = [MBProgressHUD showHUDAddedTo:windowView animated:YES];
        
    }
    
    
    
    //普通的loading模式不能有边框
    if (self.loadingType == LoadingNormal) {
        hud.bezelView.backgroundColor = [UIColor clearColor];
        if (self.isHudBackgroundClearColor) {
            self.hudBaseView.backgroundColor = [UIColor clearColor];
        }else
        {
            self.hudBaseView.backgroundColor =[UIColor colorWithWhite:0.0f alpha:0.3f];
        }
        
        
    }else
    {
        hud.bezelView.backgroundColor = [UIColor colorWithWhite:0.0f alpha:0.3f];
        self.hudBaseView.backgroundColor = [UIColor clearColor];
    }
    
    
    if (_isDIYLoading) {
        hud.label.text = _loadingTitle;
    }else
    {
        hud.label.text = @"正在加载...";
    }
    
    
    //    // 设置普通状态的动画图片,自定义loading动画
    //    NSMutableArray *idleImages = [NSMutableArray array];
    //    for (NSUInteger i = 1; i<=24; i++) {
    //        UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"%ld", (unsigned long)i]];
    //        [idleImages addObject:image];
    //    }
    //
    //
    //    UIImageView *imageV = [[UIImageView alloc]init];
    //    imageV.animationImages = idleImages;
    //    hud.mode = MBProgressHUDModeCustomView;
    //    [imageV startAnimating];
    //    hud.customView = imageV;
    //    hud.contentColor = [UIColor  whiteColor];
    
    
    
}

#pragma mark 隐藏HUD
- (void)hideHUD
{

    [hud hideAnimated:NO];
    self.hudBaseView.hidden = YES;
    
}



- (void)dealloc
{
    //获取当前类下的全部子类
    NSArray *arrayChildClass = [self findAllOf: [self  class]];
    NSString *name =   [NSString stringWithCString:object_getClassName([arrayChildClass lastObject]) encoding:NSUTF8StringEncoding];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    NSLog(@"==========%@已释放============",name);
    
}

#pragma mark 获取当前控制器下的子类
- (NSArray *)findAllOf:(Class)defaultClass

{
    int count = objc_getClassList(NULL, 0);
    if (count <= 0)
    {
        return [NSArray arrayWithObject:defaultClass];
    }
    
    NSMutableArray *output = [NSMutableArray arrayWithObject:defaultClass];
    Class *classes = (Class *) malloc(sizeof(Class) * count);
    objc_getClassList(classes, count);
    for (int i = 0; i < count; ++i)
    {
        if (defaultClass == class_getSuperclass(classes[i]))//子类
        {
            [output addObject:classes[i]];
        }
    }
    
    free(classes);
    
    return [NSArray arrayWithArray:output];
}

#pragma mark 返回上一层控制器
- (void)backLastView
{
    //如果是最底层的控制器，点击返回则回到首页选择界面
    NSArray *viewControllers = self.navigationController.viewControllers;
    if (viewControllers.count == 1) {
        return;
    }
    [self.navigationController popViewControllerAnimated:YES];
}

#pragma mark 设置是否可以右滑返回
- (void)setIsSwipGesture:(BOOL)isSwipGesture
{
    UINavigationController *navi = self.navigationController;
    if ([navi isKindOfClass:[BaseNaviController class]]) {
        BaseNaviController *baseNavi = (BaseNaviController *)navi;
        if (isSwipGesture == NO) {
            baseNavi.isSwipGesture = NO;
            baseNavi.interactivePopGestureRecognizer.enabled = NO;
            
        }else{
            baseNavi.isSwipGesture = YES;
            baseNavi.interactivePopGestureRecognizer.enabled = YES;
        }
    }
    
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
 #pragma mark - Navigation
 
 // In a storyboard-based application, you will often want to do a little preparation before navigation
 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
 // Get the new view controller using [segue destinationViewController].
 // Pass the selected object to the new view controller.
 }
 */

@end

